import json
import os

from src.log.logger import logger
from config.constants import SBOM_ELEMENT_TEMPLATE_JOSNS, SBOM_DIR
from src.lib.sbom_top_element_generate import SbomTopElementGenerate
from src.lib.sbom_packages_element_generate import SbomPackagesElementGenerate
from src.lib.sbom_files_element_generate import SbomFilesElementGenerate
from src.lib.sbom_relationships_element_generate import SbomRelationshipsElementGenerate

SBOM_TOP_ELEMENT_TEMPLATE_FILE="sbom_element_top_template.json"
SBOM_PACKAGES_ELEMENT_TEMPLATE_FILE="sbom_element_packages_template.json"
SBOM_FILES_ELEMENT_TEMPLATE_FILE="sbom_element_files_template.json"
SBOM_RELATIONSHIPS_ELEMENT_TEMPLATE_FILE="sbom_element_relationships_template.json"


class SbomGenerate:
    """
    generate sbom info for rpm
    """

    def __init__(self, rpm_path, spec_path, result_path, repo_name=""):
        """
        init rpm_path, spec_path, repo_name
        Args:
            rpm_path:
            spec_path:
            repo_name:
        Returns:
        """

        self.rpm_path = rpm_path
        self.rpm_file_name = os.path.basename(rpm_path)
        self.spec_path = spec_path
        self.result_path = result_path
        self.repo_name = repo_name
        self.top_element_data = dict()
        self.package_element_data = dict()
        self.file_element_data = dict()
        self.relationship_element_data = dict()
        self._load_sbom_element_templates()
        self._top_element_generator = SbomTopElementGenerate(self.top_element_data, self.rpm_file_name)
        self._package_element_generator = SbomPackagesElementGenerate(self.package_element_data, self.rpm_path)
        self._files_element_generator = SbomFilesElementGenerate(self.file_element_data, self.rpm_path)
    
    def merge_sbom_element_jsons(self, merge_files):
        """
        merge new sbom  element jsons to sbom.json
        Args:
        Returns:
        """
        
        data = dict()
        data = self.top_element_data
        data['packages'] = merge_files.get("packages", [])
        data['files'] = merge_files.get("files", [])
        data['relationships'] = merge_files.get("relationships", [])
        final_json='.'.join([self.rpm_file_name, 'json'])
        
        with open(os.path.join(self.result_path, final_json), 'w') as output:
            json.dump(data, output, indent=2)
        
    def _load_sbom_element_templates(self):
        """
        load all of sbom element templates's jsons
        Args:
        Returns:
        """

        with open(os.path.join(SBOM_ELEMENT_TEMPLATE_JOSNS, SBOM_TOP_ELEMENT_TEMPLATE_FILE), 'r') as file:
            self.top_element_data = json.load(file)
        with open(os.path.join(SBOM_ELEMENT_TEMPLATE_JOSNS, SBOM_PACKAGES_ELEMENT_TEMPLATE_FILE), 'r') as file:
            self.package_element_data = json.load(file)
        with open(os.path.join(SBOM_ELEMENT_TEMPLATE_JOSNS, SBOM_FILES_ELEMENT_TEMPLATE_FILE), 'r') as file:
            self.file_element_data = json.load(file)
        with open(os.path.join(SBOM_ELEMENT_TEMPLATE_JOSNS, SBOM_RELATIONSHIPS_ELEMENT_TEMPLATE_FILE), 'r') as file:
            self.relationship_element_data = json.load(file)

    def generate_sbom_top(self):
        """
        generate the top element for sbom
        Args:
        
        Returns:
        
        """
        return self._top_element_generator.generate_top_element()
        
    def generate_sbom_packages(self, rpm_info):
        """
        generate the top element for sbom
        Args:
        
        Returns:
        
        """
        return self._package_element_generator.generate_packages_element(rpm_info)
        
    def generate_sbom_files(self):
        """
        generate the top element for sbom
        Args:
        
        Returns:
        
        """
        return self._files_element_generator.generate_files_element()
    
    def generate_sbom_relationships(self, rpm_depends: list, rpms_infos: dict, rpms_rpovides: dict):
        """
        generate the top element for sbom
        Args:
        
        Returns:
        
        """
        
        relationship_element_generator = SbomRelationshipsElementGenerate(self.relationship_element_data, \
                                                                            self.rpm_path)
        spdxelementId = self.package_element_data.get('SPDXID', '')
        logger.info("start generate_relationships_element, spdxelementId: %s", spdxelementId)
        logger.info("start generate_relationships_element, rpm_depends: %s", rpm_depends)
        return relationship_element_generator.generate_relationships_element(spdxelementId, \
                                                                            rpm_depends, \
                                                                            rpms_infos, \
                                                                            rpms_rpovides)